﻿using Microsoft.Extensions.Logging;
using Polly;
using Polly.Retry;
using System.Net;
using System.Text;

namespace Model.Core.Services;

public interface IHttpClientHelper
{
    Task<string> GetAsync(string uri);
    Task<string> PostAsync(string uri, string content);
    Task PatchAsync(string uri, string content);
}

public class HttpClientHelper : IHttpClientHelper, IDisposable
{
    private readonly HttpClient _httpClient;
    private readonly ILogger<HttpClientHelper> _logger;
    //private readonly AsyncRetryPolicy _retryPolicy;
    private readonly HttpClientOptions _options;

    public HttpClientHelper(ILogger<HttpClientHelper> logger)
    {
        _options = new HttpClientOptions();
        _logger = logger;
        _httpClient = new HttpClient();
        ConfigureHttpClient();
    }

    private void ConfigureHttpClient()
    {
        _httpClient.DefaultRequestHeaders.ConnectionClose = true;
        _httpClient.Timeout = TimeSpan.FromSeconds(_options.TimeoutSeconds);
    }

    public async Task<string> GetAsync(string uri)
    {
        ValidateUri(uri);
        // return await _retryPolicy.ExecuteAsync(async () =>
        //{
        using var request = new HttpRequestMessage(HttpMethod.Get, uri);
        return await ExecuteRequestAsync(request);
        // });
    }

    //public async Task PostAsync(string uri, string content)
    //{
    //    ValidateUri(uri);
    //    using var request = new HttpRequestMessage(HttpMethod.Post, uri)
    //    {
    //        Content = new StringContent(content, Encoding.UTF8, "application/json")
    //    };
    //   return await ExecuteRequestAsync(request);
    //}
    public async Task<string> PostAsync(string uri, string content)
    {
        ValidateUri(uri);
        using var request = new HttpRequestMessage(HttpMethod.Post, uri)
        {
            Content = new StringContent(content, Encoding.UTF8, "application/json")
        };
       return await ExecuteRequestAsync(request);
    }

    public async Task PatchAsync(string uri, string content)
    {
        ValidateUri(uri);
        //   await _retryPolicy.ExecuteAsync(async () =>
        // {
        using var request = new HttpRequestMessage(HttpMethod.Patch, uri)
        {
            Content = new StringContent(content, Encoding.UTF8, "application/json")
        };
        await ExecuteRequestAsync(request);

        // });
    }

    private void ValidateUri(string uri)
    {
        if (!Uri.IsWellFormedUriString(uri, UriKind.Absolute))
        {
            _logger.LogError("无效的URI格式: {Uri}", uri);
            throw new UriFormatException($"无效的URI格式: {uri}");
        }
    }

    private async Task<string> ExecuteRequestAsync(HttpRequestMessage request)
    {
        try
        {
            _logger.LogDebug("正在发送 {Method} 请求到 {Uri}", request.Method, request.RequestUri);
            using var response = await _httpClient.SendAsync(request);
            response.EnsureSuccessStatusCode();
            var responseBody = await response.Content.ReadAsStringAsync();
            _logger.LogDebug("收到成功响应: {StatusCode} {Content}", response.StatusCode, responseBody);
            return responseBody;
        }
        catch (HttpRequestException ex)
        {
            _logger.LogError(ex, "HTTP请求失败 [{StatusCode}]: {Message}", ex.StatusCode ?? HttpStatusCode.InternalServerError, ex.Message);
            throw;
        }
        catch (UriFormatException ex)
        {
            _logger.LogError(ex, "URI格式验证失败: {Message}", ex.Message);
            throw;
        }
        catch (TaskCanceledException ex) when (!ex.CancellationToken.IsCancellationRequested)
        {
            _logger.LogError("请求超时: {Timeout}s ({Uri})", _httpClient.Timeout.TotalSeconds, request.RequestUri);
            throw;
        }
    }
    public void Dispose() => _httpClient?.Dispose();
}

public class HttpClientOptions
{
    public int TimeoutSeconds { get; set; } = 30;
    public int MaxRetries { get; set; } = 1;
}
